ホームに戻る
出典 :
関連 :
目次 :
データ・テンプレート(DataTemplate)とは
コントロールの主に Content プロパティにオブジェクトが設定されている場合、どのようにそのオブジェクトを表示するかを定義する。
特に
データバインディングを行う場合に有効で、DataTemplate を定義しておくことで様々な型をソースとすることができるとともに、
ソースの型が同じ場合でも、異なる DataTemplate を割り当てることで表示方法を柔軟にカスタマイズすることができる。
DataTemplate の作用機構
WPFにおいてコントロールの表示は ContentControl クラスが担っており、これは「 Content プロパティに設定された単一の要素を表示する」という機能を提供する。
DataTemplate は、ContentControl が表示を決定する際の基準となる。
- ContentTemplate に DataTemplate が設定されている場合、Content プロパティに ContentTemplate を適用した結果を表示する
- ContentTemplateSelector に DataTemplateSelector が設定されている場合、Content プロパティに ContentTemplateSelector が返した DataTemplate を適用した結果を表示する
- Content プロパティに設定された値の型に紐づけられた DataTemplate がある場合、その DataTemplate を適用した結果を表示する
- Content プロパティが UIElement 型ならばそのまま表示する
( UIElement にすでに親がいる場合は例外となる)
- Content プロパティに設定された値の型に紐づけられた TypeConverter で UIElement に変換するものがある場合は、変換した結果を表示する
- Content プロパティに設定された値の型に紐づけられた TypeConverter で String 型に変換するものがある場合は、String 型に変換して TextBlock にラップして表示する
- Content プロパティに設定された値の型が XmlElement の場合は、InnerText プロパティの値を TextBlock にラップして表示する
- Content プロパティに設定された値を ToString した結果を TextBlock にラップして表示する
ロジックは複雑ではあるが、端的には
- 可能な限り UIElemnt に変換する
- UIElemnt に変換できなければ文字列型に変換して TextBlock に格納して表示する
となる。Button や Label 、ListBoxItem は ContentControl を継承しているため、以下のような直感的な記述が可能である。
// Button に文字列を表示 : Content に文字列を設定
this.button.Content = "こんにちは世界";
// Button 内に Button を表示 ; Content に Button を設定
this.button.Content = new Button { Content = "ボタンの中のボタン" };
DataTemplate の適用対象
対象のコントロールが ContentControl 、ItemsControl のいずれから派生しているかによって、DataTemplate を割り当てるプロパティが異なる。
ItemsControl はコレクションをソースし、DataTemplate は ItemsControl 全体ではなく、コレクションの各項目に作用する。
| 対象のコントロール |
割り当て先のプロパティ |
ContentControl 派生 ( Button 、Label など) |
ContentTemplate |
ItemsControl 派生 ( ComboBox 、ListBox、DataGrid など) |
ItemTemplate |
DataTemplate の例
View : MainWindow.xaml
Model : Person.cs
画面表示
ここでは解説のために ListBox 中に DataTemplate を定義しているが、
リソースとして定義するほうが
再利用がしやすい。詳細は
出典元を参照。
トリガー
DataTemplate には
トリガーを含めることができる。
Model : Person.cs
View : MainWindow.xaml
画面表示
DateTemplateSelector
DateTemplateSelector は、条件に応じて DataTemplate を切り替える仕組みである。
複数の DataTemplate から条件に応じてひとつを選択する。
DateTemplateSelector の定義 : PersonDateTemplateSelector.cs
ここでは、DateTemplateSelector として PersonDateTemplateSelector を定義している。
クラスは DateTemplateSelector を継承し、SelectTemplate() メソッドで適用する DataTemplate を返す。
View : MainWindow.xaml
DataTemplate の候補である PersonTemplate1 、PersonTemplate2 は Window の Resource として定義している。
DateTemplateSelector の適用先は ListBox では ItemTemplateSelector となる( ItemTemplate ではない点に注意)。
画面表示
PersonDateTemplateSelector の定義通り、Person.Age が 40 未満ならば PersonTemplate1 が、
それ以外は PersonTemplate2 が適用される。
いずれもコントロールの外見に作用するが、
- ControlTemplate
- コントロールのすべての要素に影響する
- DataTemplate
- コントロールの Content 以下の要素に影響する
という違いがある。
ControlTemplate には ContentPresenter を含めることができ、ContentPresenter の ContentTemplate プロパティに DataTemplate を割り当てた場合は
コントロールの ContentTemplate プロパティに DataTemplate を割り当てた場合と同様の動作となる。

このため、Content 以下の要素のみを制御するのであれば DataTemplate 、
( Content を含めた)すべての要素を制御するのであれば ControlTemplate を用いることになる。